	package charts.series.dots ;
	
	import flash.display.Sprite;
	import flash.display.Graphics;
	import flash.display.BlendMode;
	import charts.series.Element;
	import caurina.transitions.Tweener;
	import caurina.transitions.Equations;
	import string.Utils;
	
	class Scat extends PointDotBase {
		
		public function new ( style:Dynamic ) {
			
			// scatter charts have x, y (not value):
			style.value = style.y;

			super( -99, new Properties({}) );// style );

			// override the basics in PointDotBase:
			this._x = style.x;
			this._y = style.y;
			this.visible = true;

			if (style.alpha == null)
				style.alpha = 1;

			this.tooltip = this.replace_magic_values( style.tip );
			this.attach_events();

			var s : Sprite;
			
			// if style.x is null then user wants a gap in the line
			if (style.x == null)
			{
				this.visible = false;
			}
			else
			{
				var haloSize: Float = 0;
				if (Reflect.hasField(style,'halo_size'))
					haloSize = style.halo_size;

				var isHollow:Bool = style.hollow;				
				if (isHollow)
				{
					// Hollow - set the fill to the background color/alpha
					var bgColor : Float;
					if (Reflect.hasField(style,'background_color'))
					{
						bgColor = string.Utils.get_color( style.background-color );
					}
					else
					{
						bgColor = style.color;
					}

					var bgAlpha: Float;
					if(Reflect.hasField(style,'background_alpha'))
						bgAlpha = style.background_alpha;
					
					this.graphics.beginFill(bgColor, bgAlpha); 
				}
				else
				{
					// set the fill to be the same color and cast(alpha,the)line
					this.graphics.beginFill( style.color, style.alpha );
				}
		
				var rotation : Float = 0;

				switch (style.type)
				{
					case 'dot':
						this.graphics.lineStyle( 0, 0, 0 );
						this.graphics.beginFill( style.color, style.alpha );
						this.graphics.drawCircle( 0, 0, style.dot_size );
						this.graphics.endFill();
						
						var s:Sprite = new Sprite();
						s.graphics.lineStyle( 0, 0, 0 );
						s.graphics.beginFill( 0, 1 );
						s.graphics.drawCircle( 0, 0, style.dot_size + haloSize );
						s.blendMode = BlendMode.ERASE;
						
						this.line_mask = s;
						/*break*/

					case 'anchor':
						this.graphics.lineStyle( style.width, style.color, style.alpha );

						rotation = 0;
						if (Reflect.hasField(style, 'rotation')) {
							rotation = style.rotation;
						}

						var sides : Float = 3;
						if (style.sides > 3) {
							sides = style.sides;
						}

						this.drawAnchor(this.graphics, this.radius, sides, rotation);
						// Check to see if part of the line needs to be erased
						//trace("haloSize = ", haloSize);
						if (haloSize > 0)
						{
							haloSize += this.radius;
							s = new Sprite();
							s.graphics.lineStyle( 0, 0, 0 );
							s.graphics.beginFill( 0, 1 );
							this.drawAnchor(s.graphics, haloSize, sides, rotation);
							s.blendMode = BlendMode.ERASE;
							s.graphics.endFill();
							this.line_mask = s;
						}
						/*break*/
					
					case 'bow':
						this.graphics.lineStyle( style.width, style.color, style.alpha );

						rotation = 0;
						if (Reflect.hasField(style, 'rotation')) {
							rotation = style.rotation;
						}
						
						this.drawBow(this.graphics, this.radius, rotation);
						// Check to see if part of the line needs to be erased
						if (haloSize > 0)
						{
							haloSize += this.radius;
							s = new Sprite();
							s.graphics.lineStyle( 0, 0, 0 );
							s.graphics.beginFill( 0, 1 );
							this.drawBow(s.graphics, haloSize, rotation);
							s.blendMode = BlendMode.ERASE;
							s.graphics.endFill();
							this.line_mask = s;
						}
						/*break*/

					case 'star':
						this.graphics.lineStyle( style.width, style.color, style.alpha );

						rotation = 0;
						if (Reflect.hasField(style, 'rotation')) {
							rotation = style.rotation;
						}
						
						this.drawStar_2(this.graphics, this.radius, rotation);
						// Check to see if part of the line needs to be erased
						if (haloSize > 0)
						{
							haloSize += this.radius;
							s = new Sprite();
							s.graphics.lineStyle( 0, 0, 0 );
							s.graphics.beginFill( 0, 1 );
							this.drawStar_2(s.graphics, haloSize, rotation);
							s.blendMode = BlendMode.ERASE;
							s.graphics.endFill();
							this.line_mask = s;
						}
						/*break*/
						
					default:
						this.graphics.drawCircle( 0, 0, this.radius );
						this.graphics.drawCircle( 0, 0, this.radius - 1 );
						this.graphics.endFill();
				}
			}
			
		}
		/*
		 function replace_magic_values( t:String ): String {
			
			t = StringTools.replace(t,'#x#', NumberUtils.formatNumber(this._x));
			t = StringTools.replace(t,'#y#', NumberUtils.formatNumber(this._y));
			t = StringTools.replace(t,'#size#', NumberUtils.formatNumber(this.radius));
			return t;
		}
		*/
		public override function set_tip( b:Bool ):Void {
			if ( b )
			{
				if ( !this.is_tip )
				{
					Tweener.addTween(this, {scaleX:1.3, time:0.4, transition:"easeoutbounce"} );
					Tweener.addTween(this, {scaleY:1.3, time:0.4, transition:"easeoutbounce" } );
					if (this.line_mask != null)
					{
						Tweener.addTween(this.line_mask, {scaleX:1.3, time:0.4, transition:"easeoutbounce"} );
						Tweener.addTween(this.line_mask, {scaleY:1.3, time:0.4, transition:"easeoutbounce" } );
					}
				}
				this.is_tip = true;
			}
			else
			{
				Tweener.removeTweens(this);
				Tweener.removeTweens(this.line_mask);
				this.scaleX = 1;
				this.scaleY = 1;
				if (this.line_mask != null)
				{
					this.line_mask.scaleX = 1;
					this.line_mask.scaleY = 1;
				}
				this.is_tip = false;
			}
		}
		
		public override function resize ( sc:ScreenCoordsBase ): Void {
			
			//
			// Look: we have a real X value, so get its screen location:
			//
			this.x = sc.get_x_from_val( this._x );
			this.y = sc.get_y_from_val( this._y, this.right_axis );
			
			// Move the mask so it is in the proper place also
			// this all needs to be moved Into the base class
			if (this.line_mask != null)
			{
				this.line_mask.x = this.x;
				this.line_mask.y = this.y;
			}
		}

		
		function drawAnchor ( aGraphics:Graphics, aRadius: Float, 
										aSides: Float, aRotation: Float ):Void 
		{
			if (aSides < 3) aSides = 3;
			if (aSides > 360) aSides = 360;
			var angle: Float = 360 / aSides;
			for ( ix in 0...(aSides+1) )
			{
				// Move start point to vertical axis (-90 degrees)
				var degrees: Float = -90 + aRotation + (ix % aSides) * angle;
				var xVal: Float = calcXOnCircle(aRadius, degrees);
				var yVal: Float = calcYOnCircle(aRadius, degrees);
				
				if (ix == 0)
				{
					aGraphics.moveTo(xVal, yVal);
				}
				else
				{
					aGraphics.lineTo(xVal, yVal);
				}
			}
		}
		
		function  drawBow ( aGraphics:Graphics, aRadius: Float, 
									aRotation: Float ):Void 
		{
			var angle: Float = 60;

			// Start at center point
			aGraphics.moveTo(0, 0);
			
			// Upper right side point (unrotated)
			var degrees: Float = -90 + aRotation + angle;
			var xVal: Float = calcXOnCircle(aRadius, degrees);
			var yVal: Float = calcYOnCircle(aRadius, degrees);
			aGraphics.lineTo(xVal, yVal);

			// Lower right side point (unrotated)
			degrees += angle;
			xVal = calcXOnCircle(aRadius, degrees);
			yVal = calcYOnCircle(aRadius, degrees);
			aGraphics.lineTo(xVal, yVal);
			
			// Back to the center
			aGraphics.lineTo(xVal, yVal);
			
			// Upper left side point (unrotated)
			degrees = -90 + aRotation - angle;
			xVal = calcXOnCircle(aRadius, degrees);
			yVal = calcYOnCircle(aRadius, degrees);
			aGraphics.lineTo(xVal, yVal);
			
			// Lower Left side point (unrotated)
			degrees -= angle;
			xVal = calcXOnCircle(aRadius, degrees);
			yVal = calcYOnCircle(aRadius, degrees);
			aGraphics.lineTo(xVal, yVal);

			// Back to the center
			aGraphics.lineTo(xVal, yVal);
		}

		 function drawStar_2( aGraphics:Graphics, aRadius: Float, 
									aRotation: Float ):Void 
		{
			var angle: Float = 360 / 10;

			// Start at top point (unrotated)
			var degrees: Float = -90 + aRotation;
			for ( ix in 0...11 )
			{
				var rad: Float;
				rad = (ix % 2 == 0) ? aRadius : aRadius/2;
				var xVal: Float = calcXOnCircle(rad, degrees);
				var yVal: Float = calcYOnCircle(rad, degrees);
				if(ix == 0)
				{
					aGraphics.moveTo(xVal, yVal);
				}
				else
				{
					aGraphics.lineTo(xVal, yVal);
				}
				degrees += angle;
			}
		}
		
		function drawStar ( aGraphics:Graphics, aRadius: Float, 
									aRotation: Float ):Void 
		{
			var angle: Float = 360 / 5;

			// Start at top point (unrotated)
			var degrees: Float = -90 + aRotation;
			for ( ix in 0...6 )
			{
				var xVal: Float = calcXOnCircle(aRadius, degrees);
				var yVal: Float = calcYOnCircle(aRadius, degrees);
				if (ix == 0)
				{
					aGraphics.moveTo(xVal, yVal);
				}
				else
				{
					aGraphics.lineTo(xVal, yVal);
				}
				// Move 2 points clockwise
				degrees += (2 * angle);
			}
		}
	}
